package edu.stu.cs.software.family.base.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import edu.stu.cs.software.family.base.dao.GenericTreeDao;
import edu.stu.cs.software.family.base.domain.BaseTreeEntity;
import edu.stu.cs.software.family.base.service.GenericTreeManager;

/**
 * 
 * @author Administrator
 *
 * @param <T>  a type variable
 * @param <LG> the primary key of long for that type
 */
@Transactional
public class GenericTreeManagerImpl<T extends BaseTreeEntity<T, LG>, LG extends Serializable>
		extends GenericManagerImpl<T, LG> implements GenericTreeManager<T, LG> {

	protected GenericTreeDao<T, LG> treeDao;

	@Override
	public List<T> getAncestors(LG id) {
		List<T> ancestors = new ArrayList<T>();
		T entity = this.treeDao.findById(id).get();
		T parent = entity.getParent();
		while (parent != null) {
			ancestors.add(parent);
			entity = parent;
			parent = entity.getParent();
		}
		return ancestors;
	}

	/**
	 * Gets the id of the subtree entity
	 */
	@Override
	public List<T> getChildren(LG id) {
		T entity = this.treeDao.findById(id).get();
		return entity.getChildren();
	}

	/**
	 * 
	 */
	@Override
	public List<T> getDescendants(LG id) {
		List<T> descendants = new ArrayList<T>();
		List<T> children = this.getChildren(id);
		if (children != null && children.size() > 0) {
			descendants.addAll(children);
			for (T t : children) {
				List<T> descendants2 = this.getDescendants(t.getId());
				descendants.addAll(descendants2);
			}
		}

		return descendants;
	}

	/**
	 * 
	 */
	@Override
	public List<T> getRoot() {
		return this.treeDao.getRoot();
	}
}
